/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Base for creating a custom VGUI class; remove the functions you don't use.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/



local PANEL = {}
local DBTable = {}

function PANEL:Init()

	self:SetTitle( " " )
	self:ShowCloseButton( false )
	
	self.DBSheets = {}
	self.TableLists = {}
	self.ContentLists = {}
	
	local SP = self
	
	local DBList = vgui.Create( "DPanelList", self )
		DBList:EnableHorizontal( false )
		DBList:EnableVerticalScrollbar( true )
		DBList:SetSpacing( 5 )
		DBList:SetPadding( 5 )
		
		self.DBList = DBList
		
	
	local FileB = vgui.Create( "DButton", self )
		FileB:SetText( "File" )
		function FileB:DoClick()
			local Menu = vgui.Create( "DMenu", self )
				Menu:AddOption( "Add Connection", function() SP:AddConn() end )
				Menu:AddOption( "Close Menu", function() Menu:Remove() end )
				Menu:AddOption( "Exit Editor", function() SP:Remove() end )
				
				Menu:SizeToContents()
				Menu:Open()
		end
		
		self.FileB = FileB
		
		
	local TabSheet = vgui.Create( "DPropertySheet", self )
		TabSheet:SetPadding( 2 )
		
		self.TabSheet = TabSheet
		
	self:SetSize( ScrW() * 0.75, ScrH() * 0.6 )
	self:Center()
	
	self:MakePopup()

end

function PANEL:AddConn()
	
	local SP = self
	local TempAdd = {}
	TempAdd.database = "Database"
	TempAdd.user = "Username"
	TempAdd.password = "Password"
	TempAdd.host = "127.0.0.1"
	TempAdd.port = 3306


	local ConnPanel = vgui.Create( "DFrame" )
		ConnPanel:SetTitle( " " )
		ConnPanel:ShowCloseButton( false )
		function ConnPanel:Paint()
			surface.SetDrawColor( Color( 15, 15, 15, 255 ) )
			surface.DrawRect( 0, 0, self:GetWide(), self:GetTall() )
		end
		
	local SaveB = vgui.Create( "DButton", ConnPanel )
		SaveB:SetText( "Save" )
		function SaveB:DoClick()
			if ! file.Exists( "DBEditor/Databases.txt" ) then
				local DATA = {}
				table.insert( DATA, TempAdd )
				file.Write( "DBEditor/Databases.txt", util.TableToKeyValues( DATA ) )
				
				SP:AddDBs()
				ConnPanel:Remove()
			else
				local ReadTable = util.KeyValuesToTable( file.Read( "DBEditor/Databases.txt" ) )
				table.insert( ReadTable, TempAdd )
				file.Write( "DBEditor/Databases.txt", util.TableToKeyValues( ReadTable ) )
				
				SP:AddDBs()
				ConnPanel:Remove()
			end
		end
		
	local ExitB = vgui.Create( "DButton", ConnPanel )
		ExitB:SetText( "Exit" )
		function ExitB:DoClick()
			ConnPanel:Remove()
		end
		
	local ConnForm = vgui.Create( "DForm", ConnPanel )
		ConnForm:SetSpacing( 5 )
		ConnForm:SetPadding( 2 )
		
	local ConnDB = vgui.Create( "DTextEntry" )
		ConnDB:SetValue( TempAdd.database )
		function ConnDB:OnTextChanged()
			TempAdd.database = ConnDB:GetValue()
		end
		
		ConnForm:AddItem( ConnDB )
		
	local ConnUser = vgui.Create( "DTextEntry" )
		ConnUser:SetValue( TempAdd.user )
		function ConnUser:OnTextChanged()
			TempAdd.user = ConnUser:GetValue()
		end
		
		ConnForm:AddItem( ConnUser )
		
	local ConnPass = vgui.Create( "DTextEntry" )
		ConnPass:SetValue( TempAdd.password )
		function ConnPass:OnTextChanged()
			TempAdd.password = ConnPass:GetValue()
		end
		
		ConnForm:AddItem( ConnPass )
		
	local ConnHost = vgui.Create( "DTextEntry" )
		ConnHost:SetValue( TempAdd.host )
		function ConnHost:OnTextChanged()
			TempAdd.host = ConnHost:GetValue()
		end
		
		ConnForm:AddItem( ConnHost )
		
	local PortOverride = vgui.Create( "DCheckBoxLabel" )
		PortOverride:SetText( "Override port?" )
		PortOverride:SetChecked( false )
		
		ConnForm:AddItem( PortOverride )
		
	local ConnPort = vgui.Create( "DTextEntry" )
		ConnPort:SetNumeric( true )
		ConnPort:SetValue( TempAdd.port )
		function ConnPort:OnTextChanged()
			if PortOverride:GetChecked() then
				TempAdd.port = ConnPort:GetValue()
			end
		end
		function PortOverride:OnChange()
			if PortOverride:GetChecked() then
				TempAdd.port = ConnPort:GetValue()
			else
				TempAdd.port = 3306
			end
		end
		
		ConnForm:AddItem( ConnPort )
		
		ConnPanel:SetSize( 125, 200 )
		ConnPanel:Center()
		ConnPanel:MakePopup()
		
		ConnForm:StretchToParent( 1, 1, 1, 25 )
		
		SaveB:AlignBottom( 1 )
		SaveB:AlignLeft( 1 )
		
		ExitB:AlignBottom( 1 )
		ExitB:AlignRight( 1 )
		

end

function PANEL:AddDBs()
	self.DBList:Clear()
	local DBs = util.KeyValuesToTable( file.Read( "DBEditor/Databases.txt" ) )
	local SP = self

	for k,v in pairs( DBs ) do
		
		local DBPanel = vgui.Create( "DPanel" )
			DBPanel:SetSize( self.DBList:GetWide(), 100 )
			function DBPanel:Paint()
				surface.SetDrawColor( 180, 180, 180, 255 )
				surface.DrawRect( 0, 0, self:GetWide(), self:GetTall() )
				
				draw.RoundedBox( 2, 2, 2, self:GetWide() - 4, self:GetTall() - 4, Color( 100, 100, 100, 255 ) )
			end
			
		local Database = vgui.Create( "DLabel", DBPanel )
			Database:SetFont( "TabLarge" )
			Database:SetText( v.database )
			Database:SizeToContents()
			Database:Center()
			Database:AlignTop( 2 )
			
		local User = vgui.Create( "DLabel", DBPanel )
			User:SetFont( "DefaultFixedOutline" )
			User:SetText( v.user )
			User:SizeToContents()
			User:Center()
			User:MoveBelow( Database, 2 )
			
		local Host = vgui.Create( "DLabel", DBPanel )
			Host:SetFont( "DefaultFixedOutline" )
			Host:SetText( v.host )
			Host:SizeToContents()
			Host:Center()
			Host:MoveBelow( User, 2 )
			
		local Port = vgui.Create( "DLabel", DBPanel )
			Port:SetFont( "DefaultFixedOutline" )
			Port:SetText( v.port )
			Port:SizeToContents()
			Port:Center()
			Port:MoveBelow( Host, 2 )
			
			
		local Connect = vgui.Create( "DButton", DBPanel )
			function Connect:Think()
				if !table.HasValue( DBTable, v.database ) then
					Connect:SetText( "Connect" )
					function Connect:DoClick()
						RunConsoleCommand( "DatabaseQuery1", v.host, v.user, v.password, v.database, v.port )
					end
				else
					Connect:SetText( "Disconnect" )
					function Connect:DoClick()
						RunConsoleCommand( "DatabaseQuery2", v.database )
					end
				end
			end
			Connect:Center()
			Connect:AlignBottom( 2 )
			
			local function DBCONNECTHOOK( um )
				local DB = um:ReadString()
				local TablesString = um:ReadString()
				table.insert( DBTable, DB )
				
				local TABLES = string.Explode( ",", TablesString )
				PrintTable( TABLES )
				
				SP:AddDBSheet( DB, TABLES )
				
			end
			usermessage.Hook( "DBCONNECT", DBCONNECTHOOK )
			
			local function DBDISCONNECTHOOK( um )
				local DB = um:ReadString()
				for k,v in pairs( DBTable ) do
					if v == DB then table.remove( DBTable, k ) break end
				end
			end
			usermessage.Hook( "DBDISCONNECT", DBDISCONNECTHOOK )
			
		self.DBList:AddItem( DBPanel )
	end
end

function PANEL:AddDBSheet( DB, TABLES )
	
	local DBSheet = vgui.Create( "DPanel", self.TabSheet )
		DBSheet:StretchToParent( 1, 1, 1, 1 )
		
	local DBContent = vgui.Create( "DPropertySheet", DBSheet )
		DBContent:SetPadding( 2 )
		DBContent:StretchToParent( 1, 1, 1, 1 )
		
	self.DBSheets.DB = DBContent
	
	self.TabSheet:AddSheet( DB, DBSheet, "gui/silkicons/table_edit", false, false, "Database: " .. DB )
	
	self:AddTableSheets( TABLES, DB )
	
end

function PANEL:AddTableSheets( TABLES, DB )
	local PropSheet = self.DBSheets.DB
	local SP = self

	if !PropSheet or !PropSheet:IsValid() then return false end
	
	for k,v in pairs( TABLES ) do
	
		local TableSheet = vgui.Create( "DPanel", PropSheet )
			TableSheet:StretchToParent( 1, 1, 1, 1 )
		
		local TableContent = vgui.Create( "DPanelList", TableSheet )
			TableContent:SetSpacing( 5 )
			TableContent:SetPadding( 2 )
			TableContent:EnableHorizontal( true )
			TableContent:EnableVerticalScrollbar( true )
			TableContent:StretchToParent( 1, 1, 1, 43 )
			function TableContent:Paint()
				draw.RoundedBox( 4, 2, 2, self:GetWide() - 4, self:GetTall() - 4, Color( 160, 160, 160, 255 ) )
			end
			
		self.TableLists[v] = TableContent
		
		PropSheet:AddSheet( v, TableSheet, "gui/silkicons/folder_go", false, false, "Table: " .. v )
		
		RunConsoleCommand( "DatabaseQuery", DB, "SHOW COLUMNS FROM " .. v, v )
		
		local function QueryHook( ply, handle, id, encoded, decoded )
			local DATA = encoded[1]
			//PrintTable( DATA )
			
			SP:AddColumns( v, DATA, DB )
		end
		datastream.Hook( "QueryStream" .. v, QueryHook )
	end
	
end

function PANEL:AddColumns( TABLE, COLUMNS, DB )

	local SP = self
	
for cn,c in pairs( COLUMNS ) do	

	local List = self.TableLists[TABLE]
	if !List or !List:IsValid() then print( "LIST FAILED" ) return false end
	
	local CName = c[1]
	
		local Column = vgui.Create( "DPanel", List )
			Column:SetSize( List:GetWide() * 0.2, List:GetTall() - 5 )
	
		
		local TitleP = vgui.Create( "DPanel", Column )
			TitleP:SetSize( Column:GetWide(), 20 )
			
		local Title = vgui.Create( "DLabel", TitleP )
			Title:SetFont( "HudHintTextLarge" )
			Title:SetText( CName )
			Title:SizeToContents()
			Title:Center()
			
		local Content = vgui.Create( "DPanelList", Column )
			Content:SetSpacing( 5 )
			Content:SetPadding( 2 )
			Content:StretchToParent( 1, 21, 1, 1)
			Content:EnableHorizontal( false )
			Content:EnableVerticalScrollbar( true )
			
		if !self.ContentLists[TABLE] then self.ContentLists[TABLE] = {} end
		//print( "TABLE: " .. TABLE )
		//print( "CName: " .. CName )
		self.ContentLists[TABLE][CName] = Content
		//print( self.ContentLists[TABLE][CName] )
		//PrintTable( self.ContentLists[TABLE] )
			
			
		RunConsoleCommand( "DatabaseQuery", DB, "SELECT " .. CName .. " FROM " .. TABLE, CName .. TABLE )	
		
		local function QueryHook( ply, handle, id, encoded, decoded )	//Change this to grab information from the column table... again. Change it to the previous method.
			local DATA = encoded[1]
			//PrintTable( DATA )
			
			print( "TABLE: " .. TABLE )
			print( "CName: " .. CName )
			SP:AddColumnsContent( DATA, TABLE, CName )
		end
		datastream.Hook( "QueryStream" .. CName .. TABLE, QueryHook )
		
		List:AddItem( Column )
		
end
	
end

function PANEL:AddColumnsContent( CCONTENT, TABLE, CName )

	//print( "TABLE: " .. TABLE )
	//print( "CName: " .. CName )
	//print( self.ContentLists[TABLE][CName] )
	
	local Content = self.ContentLists[TABLE][CName]
	if !Content or !Content:IsValid() then print( "COLUMN FAILED" ) return false end
	//print( Content )

	for dn,d in pairs( CCONTENT ) do	//The 2nd index is that of the values in d's table (The actual column values attributed with the column v )
		
		for n,e in pairs( d ) do
			//print( e )
			//if n == 1 then return end
		
			local Entry = vgui.Create( "DTextEntry" )
				Entry:SetValue( e )
				Entry.VALUE1 = CCONTENT[dn][1]
				Entry.VALUE2 = CCONTENT[dn][2]
				function Entry:OnTextChanged()
					RunConsoleCommand( "DatabaseQuery3", DB, "UPDATE " .. TABLE .. " SET " .. d .. "=" .. Entry:GetValue() .. " WHERE " .. CCONTENT[dn][1] .. "=" .. self.VALUE1 .. " AND " .. CCONTENT[dn][2] .. "=" .. self.VALUE2 )
				end
				Entry:SetSize( 50, 20 )
				
				Content:AddItem( Entry )
		end
	end

end

function PANEL:PerformLayout()
	
	self.FileB:SetSize( 30, 20 )
	self.FileB:AlignTop( 4 )
	self.FileB:AlignRight( 4 )
	
	self.TabSheet:StretchToParent( self:GetWide() * 0.26, 25, 4, 4 )
	
	self.DBList:StretchToParent( 4, 4, self:GetWide() * 0.75, 4 )
	
	if file.Exists( "DBEditor/Databases.txt" ) then
		self:AddDBs()
	end

end

function PANEL:Paint()
	//Do Painting here
	
	surface.SetDrawColor( Color( 225, 225, 225, 255 ) )
	surface.DrawRect( 0, 0, self:GetWide(), self:GetTall() )
	
	surface.SetDrawColor( Color( 15, 15, 15, 255 ) )
	surface.DrawOutlinedRect( 0, 0, self:GetWide(), self:GetTall() )
	
	draw.RoundedBox( 6, 4, 4, self:GetWide() - 8, self:GetTall() - 8, Color( 0, 0, 0, 75 ) )
	
	function self.FileB:Paint()
		surface.SetDrawColor( Color( 0, 0, 0, 80 ) )
		surface.DrawRect( 0, 0, self:GetWide(), self:GetTall() )
		
		surface.SetDrawColor( color_black )
		surface.DrawOutlinedRect( 0, 0, self:GetWide(), self:GetTall() )
	end

end

function PANEL:PaintOver()

	//Paint over self and child elements here.

end

function PANEL:Think()

	//Think stuff here

end

function PANEL:OnCursorEntered()

	//Do stuff when the cursor enters the panel

end

function PANEL:OnCursorExited()

	//Do Stuff when the cursor leaves the panel

end

function PANEL:OnMouseWheeled()

	//Do stuff when you wheel the mouse on this panel

end

function PANEL:OnMousePressed()

	//Do stuff when you press the mouse on this panel

end

function PANEL:OnMouseReleased()

	//Do stuff when you release the mouse on this panel

end

function PANEL:OnKeyCodePressed()

	//Do stuff when using keys from the keyboard on this panel. This hook uses the keycode enumerations
	//http://wiki.garrysmod.com/?title=P.OnKeyCodePressed	For more information

end

function PANEL:ActionSignal()

	//This is called on the parent frame when a child VGUI element is used. The key corresponds to what is set by Panel.SetCommand.
	//From the wiki
	
end

function PANEL:OnCursorMoved()

	//From the wiki
	//Called whenever the the mouse is moved within the panel.

end

function PANEL:DoClick()

	//For button type panels, use this. Called when you click the button.

end


//Register syntax - Desired element name, Panel to use, base class of the new element.
vgui.Register( "DBEditor", PANEL, "DFrame" )

function TestEditor( ply, command, args )
	vgui.Create( "DBEditor" )
end
concommand.Add( "TestEditor", TestEditor )